package main

import (
	"context"
	"encoding/hex"
	"fmt"
	"runtime"
	"strings"
	"time"

	wailsRuntime "github.com/wailsapp/wails/v2/pkg/runtime"
)

// App struct
type App struct {
	ctx           context.Context
	serialManager *SerialManager
	modbusParser  *ModbusParser
}

// NewApp creates a new App application struct
func NewApp() *App {
	serialManager := NewSerialManager()
	return &App{
		serialManager: serialManager,
		modbusParser:  NewModbusParser(serialManager),
	}
}

// startup is called when the app starts. The context is saved
// so we can call the runtime methods
func (a *App) startup(ctx context.Context) {
	a.ctx = ctx
}

// GetPortsList 获取可用串口列表
func (a *App) GetPortsList() ([]string, error) {
	return a.serialManager.GetPortsList()
}

// OpenPort 打开串口
func (a *App) OpenPort(config SerialConfig) error {
	err := a.serialManager.OpenPort(config)
	if err != nil {
		return err
	}

	// 启动消息监听
	go func() {
		for message := range a.serialManager.messagesChan {
			// 通知前端有新消息
			wailsRuntime.EventsEmit(a.ctx, "serial-message", message)
		}
	}()

	return nil
}

// ClosePort 关闭串口
func (a *App) ClosePort() error {
	return a.serialManager.ClosePort()
}

// SendData 发送数据
func (a *App) SendData(data string, format string) error {
	return a.serialManager.SendData(data, format)
}

// GetMessages 获取所有消息
func (a *App) GetMessages() []SerialMessage {
	return a.serialManager.GetMessages()
}

// ClearMessages 清除所有消息
func (a *App) ClearMessages() {
	a.serialManager.ClearMessages()
}

// IsPortOpen 检查串口是否打开
func (a *App) IsPortOpen() bool {
	return a.serialManager.IsPortOpen()
}

// GetCurrentConfig 获取当前配置
func (a *App) GetCurrentConfig() SerialConfig {
	return a.serialManager.GetCurrentConfig()
}

// CalculateModbusCRC 计算Modbus CRC校验
func (a *App) CalculateModbusCRC(data string) (string, error) {
	// 移除所有空格
	data = strings.ReplaceAll(data, " ", "")

	// 转换为字节数组
	bytes, err := hex.DecodeString(data)
	if err != nil {
		return "", fmt.Errorf("无效的十六进制数据: %v", err)
	}

	// 计算CRC
	crc := CalculateModbusCRC(bytes)

	// 返回CRC的十六进制表示
	return fmt.Sprintf("%04X", crc), nil
}

// AppendModbusCRC 添加Modbus CRC校验
func (a *App) AppendModbusCRC(data string) (string, error) {
	// 移除所有空格
	data = strings.ReplaceAll(data, " ", "")

	// 转换为字节数组
	bytes, err := hex.DecodeString(data)
	if err != nil {
		return "", fmt.Errorf("无效的十六进制数据: %v", err)
	}

	// 添加CRC
	result := AppendModbusCRC(bytes)

	// 返回带CRC的十六进制表示
	return hex.EncodeToString(result), nil
}

// VerifyModbusCRC 验证Modbus CRC校验
func (a *App) VerifyModbusCRC(data string) (bool, error) {
	// 移除所有空格
	data = strings.ReplaceAll(data, " ", "")

	// 转换为字节数组
	bytes, err := hex.DecodeString(data)
	if err != nil {
		return false, fmt.Errorf("无效的十六进制数据: %v", err)
	}

	// 验证CRC
	return VerifyModbusCRC(bytes), nil
}

// GetSystemInfo 获取系统信息
func (a *App) GetSystemInfo() map[string]string {
	return map[string]string{
		"os":      runtime.GOOS,
		"arch":    runtime.GOARCH,
		"version": runtime.Version(),
	}
}

// ComTxRx 发送数据并等待接收响应
// txData: 发送数据（十六进制字符串）
// rxLen: 期望接收的数据长度
// timeout: 接收超时时间（毫秒）
// 返回: 接收到的数据（十六进制字符串）, 错误信息
func (a *App) ComTxRx(txData string, rxLen int, timeoutMs int) (string, error) {
	// 移除所有空格
	txData = strings.ReplaceAll(txData, " ", "")

	// 将十六进制字符串转换为字节数组
	txBuf, err := hex.DecodeString(txData)
	if err != nil {
		return "", fmt.Errorf("无效的十六进制数据: %v", err)
	}

	txLen := len(txBuf)
	rxBuf := make([]byte, rxLen)
	timeout := time.Duration(timeoutMs) * time.Millisecond

	// 调用SerialManager的ComTxRx方法
	n, err := a.serialManager.ComTxRx(txBuf, txLen, rxBuf, rxLen, timeout)

	// 即使有错误，也返回已接收的数据
	if n > 0 {
		return hex.EncodeToString(rxBuf[:n]), err
	}

	return "", err
}

// StartModbusParser 启动Modbus解析器
func (a *App) StartModbusParser() error {
	err := a.modbusParser.Start()
	if err != nil {
		return err
	}

	// 启动事件通知
	go func() {
		ticker := time.NewTicker(500 * time.Millisecond) // 每500ms检查一次
		defer ticker.Stop()

		var lastResponse string
		for {
			<-ticker.C
			if !a.modbusParser.IsRunning() {
				break
			}

			// 获取最新响应
			response := a.modbusParser.GetLastResponse()
			if response != "" && response != lastResponse {
				lastResponse = response
				// 通知前端有新的Modbus响应
				wailsRuntime.EventsEmit(a.ctx, "modbus-response", response)
			}
		}
	}()

	return nil
}

// StopModbusParser 停止Modbus解析器
func (a *App) StopModbusParser() {
	a.modbusParser.Stop()
}

// IsModbusParserRunning 检查Modbus解析器是否正在运行
func (a *App) IsModbusParserRunning() bool {
	return a.modbusParser.IsRunning()
}

// SetModbusParserInterval 设置Modbus解析器轮询间隔（毫秒）
func (a *App) SetModbusParserInterval(intervalMs int) {
	interval := time.Duration(intervalMs) * time.Millisecond
	a.modbusParser.SetInterval(interval)
}

// GetModbusParserLastResponse 获取最后一次响应
func (a *App) GetModbusParserLastResponse() string {
	return a.modbusParser.GetLastResponse()
}

// GetModbusParserLastError 获取最后一次错误
func (a *App) GetModbusParserLastError() string {
	err := a.modbusParser.GetLastError()
	if err != nil {
		return err.Error()
	}
	return ""
}
